package com.hugehard.endpointsearch;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android.os.AsyncTask;
import android.widget.ArrayAdapter;

class ScanTask extends AsyncTask<String, String, ArrayList<InetAddress>> {
	public static final int MILLI_SEC = 80;
	public static final int PORT = 5052;
	public static final String STR_SERVER_PASS_WORD = "Server This is Hugehard.";
	public static final String STR_CLIENT_PASS_WORD = "Client This is Hugehard.";
	
	private static final int IP_COUNT = 254;
	private static final int THREAD_POOL_SIZE = 10;

	private ArrayList<String> mItemArray;
	private ArrayAdapter<String> mItemAdapter;
	private CountDownLatch mCountDownLatch;

	public ScanTask(ArrayList<String> itemArray,
			ArrayAdapter<String> itemAdapter) {
		mItemArray = itemArray;
		mItemAdapter = itemAdapter;
		mCountDownLatch = new CountDownLatch(IP_COUNT);
	}

	@Override
	protected ArrayList<InetAddress> doInBackground(String... arg0) {
		String[] myIPArray = arg0[0].split("\\.");
		InetAddress currentPingAddr;

		byte one = (byte) Integer.parseInt(myIPArray[0]);
		byte two = (byte) Integer.parseInt(myIPArray[1]);
		byte three = (byte) Integer.parseInt(myIPArray[2]);
		byte[] ipByte = new byte[4];
		ipByte[0] = one;
		ipByte[1] = two;
		ipByte[2] = three;

		ExecutorService pool = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
		ScanThread[] scanThreads = new ScanThread[IP_COUNT];

		for (int i = 0; i < IP_COUNT; i++) {
			ipByte[3] = (byte) (i + 1);
			try {
				currentPingAddr = InetAddress.getByAddress(ipByte);
				scanThreads[i] = new ScanThread(currentPingAddr,
						mCountDownLatch);
			} catch (UnknownHostException ex) {
				ex.printStackTrace();
			}
		}

		for (int i = 0; i < IP_COUNT; i++) {
			pool.execute(scanThreads[i]);
		}

		pool.shutdown();
		scanThreads = null;
		ipByte = null;
		return null;
	}

	@Override
	protected void onPostExecute(ArrayList<InetAddress> ret) {
		try {
			mCountDownLatch.await();
			mItemAdapter.notifyDataSetChanged();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	private class ScanThread extends Thread {
		private InetAddress mIP;
		private CountDownLatch mCD;

		public ScanThread(InetAddress ip, CountDownLatch cd) {
			mIP = ip;
			mCD = cd;
		}

		@Override
		public void run() {
			try {
				// Timeout for the "ping"
				// boolean bRet = mIP.isReachable(MILLI_SEC);
				boolean bRet = UDPClient.isReachable_UDP(mIP, MILLI_SEC, PORT);
//				if (bRet == false) {
//					bRet = UDPClient.isReachable_UDP(mIP, MILLI_SEC, PORT);
//				}
				if (bRet) {
					mItemArray.add(mIP.toString());
				}
				mCD.countDown();
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
	}
}